using Infrastructure.Attribute;
using Infrastructure.Extensions;
using JTZY.Model.Financial.Dto;
using JTZY.Model.Financial;
using JTZY.Repository;
using JTZY.Service.Financial.IFinancialService;
using Infrastructure;
using JTZY.Service.Business.IBusinessService;
using Microsoft.Extensions.DependencyInjection;
using Infrastructure.Enums;
using JTZY.Service.System.ISystemService;
using JTZY.Common;
using JTZY.Infrastructure.CustomException;
using static JTZY.Common.GlobalEnumVars;
using JTZY.Model.Business;

namespace JTZY.Service.Financial
{
    /// <summary>
    /// 提现记录Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(ICorecmsusertocashService), ServiceLifetime = LifeTime.Transient)]
    public class CorecmsusertocashService : BaseService<Corecmsusertocash>, ICorecmsusertocashService
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly ICorecmsareaService _corecmsareaService;

        public CorecmsusertocashService(IServiceProvider serviceProvider, ICorecmsareaService corecmsareaService)
        {
            _serviceProvider = serviceProvider;
            _corecmsareaService = corecmsareaService;
        }
        /// <summary>
        /// 查询提现记录列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<CorecmsusertocashDto> GetList(CorecmsusertocashQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable().Where(predicate.ToExpression())
                .LeftJoin<Corecmsuser>((cash, user) => cash.UserId == user.Id)
                .Select((cash, user) => new CorecmsusertocashDto
                {
                    UserId = cash.UserId,
                    UserName = user.UserName,
                    UserMobile = user.Mobile,
                    Money = cash.Money,
                    Balance = user.Balance,
                    Status = cash.Status,
                    PaymentTime = cash.PaymentTime,
                    CardNumber = cash.CardNumber,
                    AccountName = cash.AccountName,
                    AccountBank = cash.AccountBank,
                    BankAreaId = cash.BankAreaId,
                    BankName = cash.BankName,
                    Memo = cash.Memo
                })
                .ToPage(parm);

            return response;
        }


        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public CorecmsusertocashDto GetInfo(int Id)
        {
            var response = Queryable()
                .Where(x => x.Id == Id)
                .LeftJoin<Corecmsuser>((cash, user) => cash.UserId == user.Id)
                  .Select((cash, user) => new CorecmsusertocashDto
                  {
                      UserId = cash.UserId,
                      UserName = user.UserName,
                      UserMobile = user.Mobile,
                      Money = cash.Money,
                      Balance = user.Balance,
                      Status = cash.Status,
                      PaymentTime = cash.PaymentTime,
                      CardNumber = cash.CardNumber,
                      AccountName = cash.AccountName,
                      AccountBank = cash.AccountBank,
                      BankAreaId = cash.BankAreaId,
                      BankName = cash.BankName,
                      Memo = cash.Memo,
                      Id = cash.Id,
                      BankCode = cash.BankCode,
                      Withdrawals = cash.Withdrawals,
                      CreateTime = cash.CreateTime,
                      UpdateTime = cash.CreateTime,
                      Type = cash.Type,
                      Message = cash.Message,
                      AccountLicense = cash.AccountLicense,
                      PaymentVoucher = cash.PaymentVoucher,
                      BankAreaAddr=""
                  })
                .First();
            if (response != null && response.BankAreaId.HasValue)
            {
                response.BankAreaAddr = _corecmsareaService.GetAreaFullName(response.BankAreaId.Value);
            }
            return response;
        }

        /// <summary>
        /// 添加提现记录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public Corecmsusertocash AddCorecmsusertocash(Corecmsusertocash model)
        {
            return Insertable(model).ExecuteReturnEntity();
        }

        /// <summary>
        /// 修改提现记录
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int UpdateCorecmsusertocash(Corecmsusertocash model)
        {
            return Update(model, true);
        }

        /// <summary>
        /// 导出提现记录
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<CorecmsusertocashDto> ExportList(CorecmsusertocashQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .Where(predicate.ToExpression())
                .Select((it) => new CorecmsusertocashDto()
                {
                }, true)
                .ToPage(parm);

            return response;
        }

        /// <summary>
        /// 提现申请
        /// </summary>
        /// <returns></returns>
        public async Task<WebApiCallBack> Tocash(long userId, CorecmsusertocashDto dto)
        {
            var jm = new WebApiCallBack();

            using var container = _serviceProvider.CreateScope();

            var settingServices = container.ServiceProvider.GetService<ICorecmssettingService>();
            var userServices = container.ServiceProvider.GetService<ICorecmsuserService>();
            //var userBankCardServices = container.ServiceProvider.GetService<ICoreCmsUserBankCardServices>();
            var balanceServices = container.ServiceProvider.GetService<ICorecmsuserbalanceService>();

            //var allConfigs = await settingServices.GetConfigDictionaries();

            //最小提现金额
            var tocashMoneyLow = 0.01M;//CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.TocashMoneyLow).ObjectToDecimal((decimal)0.01);
            //每日提现上线
            var tocashMoneyLimit = 0M;//CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.TocashMoneyLimit).ObjectToDecimal(0);
            //提现手续费
            var tocashMoneyRate = 0M;//CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.TocashMoneyRate).ObjectToDecimal(0);
            //最低提现金额
            if (dto.Money < tocashMoneyLow)
            {
                jm.msg = "提现最低不能少于" + tocashMoneyLow + "元";
                return jm;
            }
            //每日提现上限，默认0不限制
            if (tocashMoneyLimit > 0)
            {
                var dt = DateTime.Now;
                var starTime = new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0);
                var endTime = new DateTime(dt.Year, dt.Month, dt.Day, 23, 59, 59);
                //判断历史提现金额  
                var todayMoney = await Queryable().Where(p => p.CreateTime >= starTime && p.CreateTime <= endTime && p.UserId == userId).SumAsync<decimal>("money");
                todayMoney = todayMoney + dto.Money; //历史今天提现加上本次提现;
                if (todayMoney > tocashMoneyLimit)
                {
                    jm.msg = "每日提现不能超过" + tocashMoneyLimit + "元";
                    return jm;
                }
            }
            var userInfo = await userServices.GetByIdAsync(userId);
            if (userInfo == null)
            {
                jm.msg = "非法用户";
                return jm;
            }
            if (dto.Money > userInfo.Balance)
            {
                jm.msg = "余额不足";
                return jm;
            }
            // 计算提现服务费(金额)
            var cateMoney = dto.Money * (tocashMoneyRate / 100);
            if (cateMoney + dto.Money > userInfo.Balance)
            {
                jm.msg = "余额不足";
                return jm;
            }
            //获取银行卡信息
            //var bankcardsInfo = await userBankCardServices.QueryByClauseAsync(p => p.userId == userId && p.id == bankCardsId);
            //if (bankcardsInfo == null)
            //{
            //    jm.msg = GlobalErrorCodeVars.Code11016;
            //    return jm;
            //}
            var cashModel = new Corecmsusertocash();
            cashModel.UserId = userId;
            cashModel.Money = dto.Money;
            cashModel.BankName = dto.BankName;
            //cashModel.BankCode = dto.bankCode;
            //cashModel.BankAreaId = bankcardsInfo.bankAreaId;
            cashModel.AccountBank = dto.AccountBank;
            cashModel.AccountName = dto.AccountName;
            cashModel.CardNumber = dto.CardNumber;
            cashModel.Status = (int)UserTocashStatus.待审核;
            cashModel.Withdrawals = cateMoney;
            cashModel.CreateTime = DateTime.Now;
            cashModel.Type = (int)UserTocashType.银行线下转账;
            cashModel.Balance = userInfo.Balance - dto.Money;
            //ALTER TABLE jtzydb.corecmsusertocash ADD balance DECIMAL(10,2) NULL COMMENT '当前余额';

            var res = await InsertReturnIdentityAsync(cashModel);
            if (res > 0)
            {
                var change = await balanceServices.Change(userId, (int)UserBalanceSourceTypes.Tocash, dto.Money, res.ToString(), cateMoney);
                jm.status = change.status;
                jm.msg = jm.status ? "提现申请成功" : "提现申请失败";
                jm.data = change.data;
                jm.otherData = change.otherData;
            }
            else
            {
                jm.msg = "提现申请失败";
            }

            return jm;
        }

        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<Corecmsusertocash> QueryExp(CorecmsusertocashQueryDto parm)
        {
            var predicate = Expressionable.Create<Corecmsusertocash>();
            predicate = predicate.And(it=>it.UserId==parm.UserId);
            predicate = predicate.AndIF(parm.BeginCreateTime == null, it => it.CreateTime >= DateTime.Now.AddDays(-365).ToShortDateString().ParseToDateTime());
            predicate = predicate.AndIF(parm.BeginCreateTime != null, it => it.CreateTime >= parm.BeginCreateTime);
            predicate = predicate.AndIF(parm.EndCreateTime != null, it => it.CreateTime <= parm.EndCreateTime);
            return predicate;
        }

        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public CorecmsusertocashDto GetLastCashInfo(long userId)
        {
            var response = Queryable()
                .Where(x => x.UserId==userId)
               
                .OrderBy((cash) => cash.CreateTime, OrderByType.Desc)
                  .Select((cash) => new CorecmsusertocashDto
                  {
                    
                      Status = cash.Status,
                      CardNumber = cash.CardNumber,
                      AccountName = cash.AccountName,
                      AccountBank = cash.AccountBank,
                      BankAreaId = cash.BankAreaId,
                      BankName = cash.BankName,
                      Memo = cash.Memo,
                      BankCode = cash.BankCode,
                      //Withdrawals = cash.Withdrawals,
                      //Type = cash.Type,
                      //Message = cash.Message,
                      AccountLicense = cash.AccountLicense,
                      //PaymentVoucher = cash.PaymentVoucher,
                      BankAreaAddr = ""
                  })
                .First();
            if (response != null && response.BankAreaId.HasValue)
            {
                response.BankAreaAddr = _corecmsareaService.GetAreaFullName(response.BankAreaId.Value);
            }
            return response;
        }
    }
}